package com.pine.manager.pineframework.trigger.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.pine.common.beans.exception.BusinessException;
import com.pine.common.beans.exception.ExceptionCodeEnum;
import com.pine.common.beans.pineframework.request.SysUserLoginRequest;
import com.pine.common.beans.pineframework.response.SysUserLoginResponse;
import com.pine.common.trigger.AbstractTriggerTemplate;
import com.pine.common.trigger.TriggerContext;
import com.pine.common.util.user.UserUtil;
import com.pine.dao.pineframework.constants.StatusEnum;
import com.pine.manager.core.CipherComponent;
import com.pine.manager.core.SysUserInfo;
import com.pine.manager.core.TriggerTypeEnum;
import com.pine.manager.pineframework.SysUserManager;
import com.pine.manager.pineframework.bo.SysUserBo;
import com.pine.manager.pineframework.query.SysUserQuery;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

/**
 * 用户登录触发器
 *
 * @author pine manage
 * @since 2024-08-14
 */
@Component
@Slf4j
public class SysUserLoginTrigger extends AbstractTriggerTemplate<SysUserLoginRequest, SysUserLoginResponse> {
    private SysUserBo sysUserBo;

    private String tokenValue;

    @Resource
    private SysUserManager sysUserManager;
    @Resource
    private CipherComponent cipherComponent;

    public SysUserLoginTrigger() {
        super(TriggerTypeEnum.SYS_USER_LOGIN);
    }

    @Override
    protected void before(TriggerContext<SysUserLoginRequest> triggerContext) {
        sysUserBo = null;
        tokenValue = null;
        SysUserLoginRequest request = triggerContext.getTriggerRequest();
        SysUserQuery sysUserQuery = new SysUserQuery();
        sysUserQuery.setLoginAccount(request.getLoginAccount());
        sysUserBo = sysUserManager.getOne(sysUserQuery);

        // 判断用户是否存在
        if (ObjectUtils.isEmpty(sysUserBo)) {
            throw new BusinessException(ExceptionCodeEnum.USER_NOT_EXIST);
        }

        // 验证密码
        String passwordEncrypt = cipherComponent.aesEncrypt(request.getPassword());
        if (!passwordEncrypt.equals(sysUserBo.getPassword())) {
            throw new BusinessException(ExceptionCodeEnum.USER_NOT_MATCH);
        }

        // 验证用户状态，是否被禁用
        if (!StatusEnum.ENABLE.equals(sysUserBo.getStatus())) {
            throw new BusinessException(ExceptionCodeEnum.USER_DISABLED);
        }
    }

    /**
     * 触发
     *
     * @param triggerContext 触发上下文
     * @return 触发结果
     */
    @Override
    public SysUserLoginResponse trigger(TriggerContext<SysUserLoginRequest> triggerContext) {
        // 根据用户ID登录
        StpUtil.login(sysUserBo.getId());
        // 设置当前用户token信息
        tokenValue = StpUtil.getTokenValueByLoginId(sysUserBo.getId());

        // 组装响应
        SysUserLoginResponse loginResponse = new SysUserLoginResponse();
        loginResponse.setToken(tokenValue);
        loginResponse.setLoginAccount(sysUserBo.getLoginAccount());
        loginResponse.setUsername(sysUserBo.getUsername());
        loginResponse.setAvatar(sysUserBo.getAvatar());
        loginResponse.setId(sysUserBo.getId());
        loginResponse.setExpireTime(StpUtil.getTokenTimeout(tokenValue));

        // 设置用户信息
        SysUserInfo sysUserInfo = new SysUserInfo();
        sysUserInfo.setId(sysUserBo.getId());
        sysUserInfo.setUsername(sysUserBo.getUsername());
        sysUserInfo.setToken(tokenValue);
        UserUtil.set(sysUserInfo);
        return loginResponse;
    }
}
